/* Sokoban
 * HIT3243
 * Authors: Mike Blackney, Ben Ingarfield, Kurniawan
 */

#include "game.h"
#include "registrar.h"

// Interface placement:
#define TIME_X 650
#define TIME_Y 25
#define TIME_POSITION D3DXVECTOR2(TIME_X,TIME_Y+35)
#define TURNS_X 100
#define TURNS_Y 25
#define TURNS_POSITION D3DXVECTOR2(TURNS_X,TURNS_Y+35)
#define PUSHES_X 100
#define PUSHES_Y 75
#define PUSHES_POSITION D3DXVECTOR2(PUSHES_X,PUSHES_Y+35)

Game::Game( ) 
: level( *Registrar::pLevel ) {
}

Game* const Game::Instance( ) {
	static Game instance;
	return &instance;
}

HRESULT Game::Load( ) {

	HRESULT hr;

	// Load a font for the score:
	V_RETURN(font.Load(L"Tahoma", 24, FW_NORMAL));
	
	V_RETURN(time.CreateFromFile(L"s_time.jpg"));
	time.SetPosition( TIME_X-time.GetWidth( )/2, TIME_Y );

	V_RETURN(turns.CreateFromFile(L"s_turns.jpg"));
	turns.SetPosition( TURNS_X-turns.GetWidth( )/2, TURNS_Y );

	V_RETURN(pushes.CreateFromFile(L"s_pushes.jpg"));
	pushes.SetPosition( PUSHES_X-pushes.GetWidth( )/2, PUSHES_Y );

	level.Load( );
	V_RETURN( level.PrepareGame( 0 ) );

	DXUTSetCursorSettings(false, false);
	DXUTGetD3DDevice( )->ShowCursor(false);

	return S_OK;
}

void Game::Unload( ) {
	level.Unload( );
	font.Unload( );
	time.Unload( );
	turns.Unload( ),
	pushes.Unload( );
}

void Game::Update(double fTime, float fElapsedTime) {

	// Update the time:
	Registrar::fTime += fElapsedTime;

	level.Update( fTime, fElapsedTime );

}


HRESULT Game::OnCreateDevice( IDirect3DDevice9* device, const D3DSURFACE_DESC* surface ) {
	// Pass the info on to the level:
	return level.OnCreateDevice( device, surface );
}

HRESULT Game::OnResetDevice( IDirect3DDevice9* device, const D3DSURFACE_DESC* surface ) {
	// Pass the info on to the level:
	return level.OnResetDevice( device, surface );
}

void Game::OnLostDevice( ) {
	// Tell the level:
	level.OnLostDevice( );
}

void Game::Render3D(double fTime, float fElapsedTime) {
	// Render the level's 3d:
	level.Render3D( fTime, fElapsedTime );
}

void Game::Render2D(double fTime, float fElapsedTime) {

	// Render the level's 2d:
	level.Render2D( fTime, fElapsedTime );

	// Now render the scores, etc.:
	time.Render2D( );
	turns.Render2D( );
	pushes.Render2D( );

	font.Render2D( dxf::towstring( static_cast<int>(Registrar::fTime) ), TIME_POSITION );
	font.Render2D( dxf::towstring(Registrar::iNumTurns), TURNS_POSITION );
	font.Render2D( dxf::towstring(Registrar::iNumPushes), PUSHES_POSITION );

}

void Game::Resize(const D3DSURFACE_DESC* d) {
}

bool Game::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	// Pressing ESC during the game will take you to the High Score list:
	if (uMsg == WM_KEYDOWN && wParam == VK_ESCAPE) {
		Registrar::bEnteringScore = false;
		dxf::DXFChangeState(Registrar::kHiScore);
		return true;
	}

	return level.MsgProc(hWnd,uMsg,wParam,lParam);
}
